from enum import Enum, unique


class ApiConstants:
    RESOURCE_MATCHED_STATUS_MATCHED = "MATCHED"
    RESOURCE_MATCHED_STATUS_JOB_URL_ERROR = "ERROR_JOB_URL"
    RESOURCE_MATCHED_STATUS_INVALID_PARAMS = "INVALID_PARAMS"
    RESOURCE_MATCHED_STATUS_BLOCKED = "BLOCKED"
    RESOURCE_MATCHED_STATUS_QUEUED = \
        """
        No resource available now, job queued in waiting queue
        """
    RESOURCE_MATCHED_STATUS_QUEUED_FOR_DEPLOY = \
        """
        No resource available now, please modify the resource type or try it again later
        """
    RESOURCE_MATCHED_STATUS_QUEUE_CANCELED = "QUEUE_CANCELED"

    RESOURCE_MATCHED_STATUS_BIND_CREDIT_CARD_FIRST = \
        """
        Before we can start a job, please add a credit card to your FEDML account at https://fedml.ai/billing/home.
        Once it's added, please try to run the launch command again
        """

    RESOURCE_MATCHED_STATUS_QUERY_CREDIT_CARD_BINDING_STATUS_FAILED = "QUERY_CREDIT_CARD_BINDING_STATUS_FAILED"

    RESOURCE_MATCHED_STATUS_NO_RESOURCES = "NO_RESOURCES"
    RESOURCE_MATCHED_STATUS_REQUEST_FAILED = "REQUEST_FAILED"
    RESOURCE_MATCHED_STATUS_FAILED = "FAILED"

    LAUNCHED = "Your job has been launched successfully."
    LAUNCH_JOB_STATUS_REQUEST_FAILED = "LAUNCH_REQUEST_FAILED"
    LAUNCH_JOB_STATUS_JOB_URL_ERROR = "LAUNCH_ERROR_JOB_URL"
    LAUNCH_JOB_STATUS_JOB_CANCELED = "LAUNCH_ERROR_JOB_CANCELED"
    LAUNCH_JOB_STATUS_NO_JOBS = "LAUNCH_ERROR_NO_JOBS"
    LAUNCH_JOB_STATUS_INVALID = "LAUNCH_JOB_STATUS_INVALID"

    LAUNCH_JOB_STATUS_BLOCKED = \
        """
        Because the value of maximum_cost_per_hour is too low, we can not find exactly matched machines for your job.
        """

    LAUNCH_JOB_STATUS_QUERY_USER_BALANCE_FAILED = "QUERY_USER_BALANCE_FAILED"
    LAUNCH_JOB_STATUS_USER_BALANCE_NOT_ENOUGH = "USER_BALANCE_NOT_ENOUGH"
    LAUNCH_JOB_STATUS_JOB_NOT_EXISTS = "JOB_NOT_EXISTS"
    LAUNCH_JOB_STATUS_MACHINE_STARTUP_FAILED = "MACHINE_STARTUP_FAILED"
    LAUNCH_JOB_STATUS_CREATE_PROJECT_FAILED = "CREATE_PROJECT_FAILED"
    LAUNCH_JOB_STATUS_PROJECT_NOT_EXISTS = "PROJECT_NOT_EXISTS"
    LAUNCH_JOB_STATUS_DB_INSERT_ERROR = "DB_INSERT_ERROR"
    LAUNCH_JOB_STATUS_OCCUPIED_FAILED = "OCCUPIED_FAILED"
    LAUNCH_JOB_STATUS_JOB_CONFIG_NOT_EXISTS = "JOB_CONFIG_NOT_EXISTS"
    LAUNCH_JOB_STATUS_GENERAL_ERROR = "LAUNCH_JOB_GENERAL_ERROR"
    LAUNCH_JOB_STATUS_NO_SPECIFIC_ERROR = "LAUNCH_JOB_STATUS_NO_SPECIFIC_ERROR"

    CLUSTER_CREATION_FAILED = "CLUSTER_CREATION_FAILED"
    CLUSTER_CONFIRM_FAILED = "CLUSTER_CONFIRM_FAILED"
    CLUSTER_CONFIRM_SUCCESS = "CLUSTER_CONFIRM_SUCCESS"

    APP_UPDATE_FAILED = "APP_UPDATE_FAILED"
    ERROR = "ERROR"

    ERROR_CODE = {LAUNCHED: 0, RESOURCE_MATCHED_STATUS_MATCHED: 1,
                  RESOURCE_MATCHED_STATUS_JOB_URL_ERROR: 2, RESOURCE_MATCHED_STATUS_INVALID_PARAMS: 3,
                  RESOURCE_MATCHED_STATUS_BLOCKED: 4, RESOURCE_MATCHED_STATUS_QUEUED: 5,
                  RESOURCE_MATCHED_STATUS_BIND_CREDIT_CARD_FIRST: 6,
                  RESOURCE_MATCHED_STATUS_QUERY_CREDIT_CARD_BINDING_STATUS_FAILED: 7,
                  RESOURCE_MATCHED_STATUS_NO_RESOURCES: 8, RESOURCE_MATCHED_STATUS_REQUEST_FAILED: 9,
                  LAUNCH_JOB_STATUS_REQUEST_FAILED: 10, LAUNCH_JOB_STATUS_JOB_URL_ERROR: 11,
                  LAUNCH_JOB_STATUS_JOB_CANCELED: 12, LAUNCH_JOB_STATUS_NO_JOBS: 13,
                  RESOURCE_MATCHED_STATUS_QUEUE_CANCELED: 14, CLUSTER_CONFIRM_FAILED: 15, CLUSTER_CREATION_FAILED: 16,
                  LAUNCH_JOB_STATUS_INVALID: 17, LAUNCH_JOB_STATUS_BLOCKED: 18, APP_UPDATE_FAILED: 19, ERROR: 20,
                  LAUNCH_JOB_STATUS_GENERAL_ERROR: 21, LAUNCH_JOB_STATUS_NO_SPECIFIC_ERROR: 22,
                  LAUNCH_JOB_STATUS_QUERY_USER_BALANCE_FAILED: 23, LAUNCH_JOB_STATUS_USER_BALANCE_NOT_ENOUGH: 24,
                  LAUNCH_JOB_STATUS_JOB_NOT_EXISTS: 25, LAUNCH_JOB_STATUS_MACHINE_STARTUP_FAILED: 26,
                  LAUNCH_JOB_STATUS_CREATE_PROJECT_FAILED: 27, LAUNCH_JOB_STATUS_PROJECT_NOT_EXISTS: 28,
                  LAUNCH_JOB_STATUS_DB_INSERT_ERROR: 29, LAUNCH_JOB_STATUS_OCCUPIED_FAILED: 30,
                  LAUNCH_JOB_STATUS_JOB_CONFIG_NOT_EXISTS: 31}


@unique
class RunStatus(Enum):
    NOT_STARTED = "NOT_STARTED"
    QUEUED = "QUEUED"
    STARTING = "STARTING"
    RUNNING = "RUNNING"
    STOPPING = "STOPPING"
    KILLED = "KILLED"
    FAILED = "FAILED"
    FINISHED = "FINISHED"
    ABANDONED = "ABANDONED"
    LAUNCHED = "LAUNCHED"
    ERROR = "ERROR"
    BLOCKED = "BLOCKED"
    PRE_QUEUE = "PRE_QUEUE"
    INVALID = "INVALID"
    CLUSTER_QUEUE = "CLUSTER_QUEUE"
    PROVISIONING = "PROVISIONING"
    UNDETERMINED = "UNDETERMINED"

    def __str__(self):
        return self.value

    @classmethod
    def get_run_enum_from_str(cls, run_status_str: str):
        for run_status in cls:
            if run_status.value == run_status_str:
                return run_status
        return cls.UNDETERMINED

